package gui.panel_new.evaluation.professor;

import enums.FileFilterEnum;
import enums.TextBundleEnum;
import enums.URLEnum;
import gui.other.JComponentCellRenderer;
import gui.other.TruthTableOperatorsDialog;
import gui.panel_new.evaluation.exeptions.ExerciseNotBuiltException;
import gui.panel_new.evaluation.exeptions.PunctuationZeroException;
import j_util.Utiles;
import misc.BundlesProvider;
import model.TruthTable;
import model.eval.TestExcercise;
import model.eval.TestTruthTable;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
/*

    This file is part of Logica-Logike.

    Logica-Logike is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation version 3 of the License.

    Logica-Logike is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Logica-Logike.  If not, see <http://www.gnu.org/licenses/>.

 */
/**
 * Extension de CreateExercisePanel, permite la creacion de ejercicios de evaluacion relacionados de tablas de verdad;
 *
 * @author Jose Martin Rozanec;
 */
public class CreateTruthTablePanel extends CreateExercisePanel {
    private javax.swing.JButton acceptButton;
    private javax.swing.JButton bicondicionalButton;
    private javax.swing.JButton calcularTabla;
    private javax.swing.JButton resetButton;
    private javax.swing.JButton condicionalButton;
    private javax.swing.JButton conjuncionButton;
    private javax.swing.JPanel cuadroPanel;
    private javax.swing.JButton disyuncionExcButton;
    private javax.swing.JButton disyuncionIncButton;
    private javax.swing.JButton incompatibilidadButton;
    private javax.swing.JTextField inputTextField;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JButton negacionButton;
    private javax.swing.JButton negacionConjuntaButton;
    private javax.swing.JPanel operadoresPanel;
    private javax.swing.JTable table;
    private javax.swing.JLabel variableIngresarLabel;
    private javax.swing.JButton joinTablesButton;

    private JLabel addsPoints;
    private JLabel substractPoints;
    private JTextField addsPointsField;
    private JTextField substractPointsField;

    private String parentesisOperando;
    private String operandoOperando;

    private List<String> tableTitles;
    private TruthTable truthTable;
    private String listSize0;

    private ResourceBundle textBundle;

    /**
     * Constructor;
     *
     * @param saveButton;
     * @param openButton;
     * @param fileChooser;
     */
    public CreateTruthTablePanel(JButton saveButton, JButton openButton, JFileChooser fileChooser) {
        this.saveButton = saveButton;
        this.openButton = openButton;
        this.fileChooser = fileChooser;
        fileFilter = FileFilterEnum.XML;
        tableTitles = new ArrayList<String>();
        textBundle = BundlesProvider.getBundle(URLEnum.TEXT_BUNDLE);
        initComponents();
    }

    /**
     * Inicializa los componentes y realiza el layout de los componentes visuales;
     */
    private void initComponents() {
        parentesisOperando = textBundle.getString(TextBundleEnum.WARNING_PARENTESIS_OPERANDO.toString()) + "!";
        operandoOperando = textBundle.getString(TextBundleEnum.WARNING_OPERANDO_OPERANDO.toString()) + "!";
        listSize0 = textBundle.getString(TextBundleEnum.WARNING_INICIO_OPERANDO.toString()) + "!";
        mainPanel = new javax.swing.JPanel();
        cuadroPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        table = new javax.swing.JTable();
        operadoresPanel = new javax.swing.JPanel();
        negacionButton = new javax.swing.JButton();
        conjuncionButton = new javax.swing.JButton();
        disyuncionIncButton = new javax.swing.JButton();
        disyuncionExcButton = new javax.swing.JButton();
        condicionalButton = new javax.swing.JButton();
        bicondicionalButton = new javax.swing.JButton();
        negacionConjuntaButton = new javax.swing.JButton();
        incompatibilidadButton = new javax.swing.JButton();
        inputTextField = new javax.swing.JTextField();
        variableIngresarLabel = new javax.swing.JLabel();
        acceptButton = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JSeparator();
        calcularTabla = new javax.swing.JButton();
        resetButton = new javax.swing.JButton();
        jSeparator2 = new javax.swing.JSeparator();
        joinTablesButton = new javax.swing.JButton();

        mainPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(
                new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true),
                textBundle.getString(TextBundleEnum.TABLA_VERDAD.toString())));

        cuadroPanel.setBackground(new java.awt.Color(255, 255, 255));
        cuadroPanel.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));

        jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
        jScrollPane1.setBorder(null);
        jScrollPane1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        jScrollPane1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

        table.setModel(new javax.swing.table.DefaultTableModel(
                new Object[][]{
                },
                new String[]{
                        "", "", "", ""
                }
        ));

        table.setForeground(Color.BLACK);
        table.setBackground(Color.WHITE);
        table.getTableHeader().setReorderingAllowed(false);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        jScrollPane1.setViewportView(table);
        jScrollPane1.setPreferredSize(new Dimension(630, 470));//500//todo

        jScrollPane1.setBorder(javax.swing.BorderFactory.createTitledBorder(
                BorderFactory.createEtchedBorder(),//new javax.swing.border.LineBorder(Color.BLACK, 1, true)
                textBundle.getString(TextBundleEnum.TABLA_VERDAD.toString())));

        operadoresPanel.setBackground(new java.awt.Color(255, 255, 255));
        operadoresPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(
                BorderFactory.createMatteBorder(1,0,0,0,Color.LIGHT_GRAY),//new javax.swing.border.LineBorder(Color.BLACK, 1, true)
                textBundle.getString(TextBundleEnum.OPERADORES_VARIABLES.toString())));


        negacionButton.setText(textBundle.getString(TextBundleEnum.NEGACION.toString()));
        negacionButton.setMnemonic('q');
        negacionButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                negacionButtonActionPerformed();
            }
        });

        conjuncionButton.setText(textBundle.getString(TextBundleEnum.CONJUNCION.toString()));
        conjuncionButton.setMnemonic('a');
        conjuncionButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                conjuncionButtonActionPerformed();
            }
        });

        disyuncionIncButton.setText(textBundle.getString(TextBundleEnum.DISYUNCION_INCLUSIVA.toString()));
        disyuncionIncButton.setMnemonic('w');
        disyuncionIncButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                disyuncionInclusivaButtonActionPerformed();
            }
        });

        disyuncionExcButton.setText(textBundle.getString(TextBundleEnum.DISYUNCION_EXCLUSIVA.toString()));
        disyuncionExcButton.setMnemonic('s');
        disyuncionExcButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                disyuncionExclusivaButtonActionPerformed();
            }
        });

        condicionalButton.setText(textBundle.getString(TextBundleEnum.CONDICIONAL.toString()));
        condicionalButton.setMnemonic('e');
        condicionalButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                condicionalButtonActionPerformed();
            }
        });

        bicondicionalButton.setText(textBundle.getString(TextBundleEnum.BICONDICIONAL.toString()));
        bicondicionalButton.setMnemonic('d');
        bicondicionalButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                bicondicionalButtonActionPerformed();
            }
        });

        negacionConjuntaButton.setText(textBundle.getString(TextBundleEnum.NEGACION_CONJUNTA.toString()));
        negacionConjuntaButton.setMnemonic('r');
        negacionConjuntaButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                negacionConjuntaButtonActionPerformed();
            }
        });

        incompatibilidadButton.setText(textBundle.getString(TextBundleEnum.INCOMPATIBILIDAD.toString()));
        incompatibilidadButton.setMnemonic('f');
        incompatibilidadButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                incompatibilidadButtonActionPerformed();
            }
        });

//        variableIngresarLabel.setText("Ingresar variable o parentesis:"/);
        variableIngresarLabel.setIcon(Utiles.createImageIcon(URLEnum.getReference(URLEnum.INGRESAR_VARIABLE_PARENTESIS)));
        acceptButton.setText(textBundle.getString(TextBundleEnum.ACEPTAR.toString()));
        acceptButton.setMnemonic('z');
        acceptButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                acceptButtonActionPerformed();
            }
        });

        jSeparator1.setForeground(new java.awt.Color(0, 0, 0));
        jSeparator1.setOrientation(JSeparator.HORIZONTAL);
        jSeparator1.setPreferredSize(new Dimension(650, 10));

        joinTablesButton.setText(textBundle.getString(TextBundleEnum.UNIR_TABLAS.toString()));
        joinTablesButton.setMnemonic('x');
        joinTablesButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                TruthTableOperatorsDialog truthTableOperatorsDialog = new TruthTableOperatorsDialog(fileChooser);
                truthTableOperatorsDialog.setPreferredSize(new Dimension(640, 490));
                truthTableOperatorsDialog.setMinimumSize(new Dimension(640, 490));
                truthTableOperatorsDialog.setModal(true);
                truthTableOperatorsDialog.setVisible(true);
                if (truthTableOperatorsDialog.isAccepted()) {
                    truthTable = new TruthTable(buildExpression());
                    truthTable = truthTable.joinTable(truthTableOperatorsDialog.getOperator(),
                            truthTableOperatorsDialog.getTruthTable(), truthTableOperatorsDialog.isBeforeOperator());
                    resetearButtonActionPerformed();
                    getTableHeader(truthTable);
                    displayTruthTable();
                }
                fileChooser.setControlButtonsAreShown(true);
            }
        });

        calcularTabla.setText(textBundle.getString(TextBundleEnum.CALCULAR_TABLA.toString()));
        calcularTabla.setMnemonic('c');
        calcularTabla.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                truthTable = new TruthTable(buildExpression());
                displayTruthTable();
            }
        });

        resetButton.setText(textBundle.getString(TextBundleEnum.RESET.toString()));
        resetButton.setMnemonic('v');
        resetButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                resetearButtonActionPerformed();
            }
        });

        jSeparator2.setForeground(new java.awt.Color(0, 0, 0));

        setLayout(new GridBagLayout());
        operadoresPanel.setLayout(new GridBagLayout());
//        operadoresPanel.setBorder();
        Dimension buttonsDimension = new Dimension(155, 25);
        negacionButton.setPreferredSize(buttonsDimension);
        conjuncionButton.setPreferredSize(buttonsDimension);
        disyuncionExcButton.setPreferredSize(buttonsDimension);
        disyuncionIncButton.setPreferredSize(buttonsDimension);
        condicionalButton.setPreferredSize(buttonsDimension);
        bicondicionalButton.setPreferredSize(buttonsDimension);
        negacionConjuntaButton.setPreferredSize(buttonsDimension);
        incompatibilidadButton.setPreferredSize(buttonsDimension);
        acceptButton.setPreferredSize(buttonsDimension);
        joinTablesButton.setPreferredSize(buttonsDimension);
        calcularTabla.setPreferredSize(buttonsDimension);
        resetButton.setPreferredSize(buttonsDimension);
        inputTextField.setPreferredSize(buttonsDimension);
        inputTextField.setFont(new Font("Tahoma", 1, 16));
        setBackground(Color.WHITE);

        addsPoints = new JLabel(textBundle.getString(TextBundleEnum.SUMA.toString()));
        substractPoints = new JLabel(textBundle.getString(TextBundleEnum.RESTA.toString()));
        addsPointsField = new JTextField(7);
        substractPointsField = new JTextField(7);
        addsPointsField.setText("10");
        addsPointsField.setEditable(true);
        substractPointsField.setText("5");
        substractPointsField.setEditable(true);

        GridBagConstraints gridBagConstraints = new GridBagConstraints();
        int gridx = 0;
        int gridy = 0;
        gridBagConstraints.gridy = gridy;
        gridBagConstraints.gridx = gridx;
        gridBagConstraints.gridheight = 1;
        gridBagConstraints.gridwidth = 1;
        operadoresPanel.add(negacionButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(disyuncionIncButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(condicionalButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(negacionConjuntaButton, gridBagConstraints);
        gridx = 0;
        gridBagConstraints.gridy = ++gridy;
        gridBagConstraints.gridx = gridx;
        operadoresPanel.add(conjuncionButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(disyuncionExcButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(bicondicionalButton, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(incompatibilidadButton, gridBagConstraints);
        gridx = 0;
        gridBagConstraints.gridy = ++gridy;
        gridBagConstraints.gridx = gridx;
        gridBagConstraints.gridwidth = 4;

        operadoresPanel.add(getOperatorsPanelSeparator(), gridBagConstraints);
//        operadoresPanel.add(new JLabel(
//                Utiles.createImageIcon(URLEnum.getReference(URLEnum.TABLE_SEPARATOR))), gridBagConstraints);
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.gridy = ++gridy;
        operadoresPanel.add(variableIngresarLabel, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        gridBagConstraints.gridx = ++gridx;
        gridBagConstraints.gridwidth = 1;
        operadoresPanel.add(inputTextField, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(acceptButton, gridBagConstraints);
        gridBagConstraints.gridy = ++gridy;
        gridBagConstraints.gridwidth = 4;
        gridx = 0;
        gridBagConstraints.gridx = gridx;
        operadoresPanel.add(getOperatorsPanelSeparator(), gridBagConstraints);
//        operadoresPanel.add(new JLabel(
//                Utiles.createImageIcon(URLEnum.getReference(URLEnum.TABLE_SEPARATOR))), gridBagConstraints);
        gridBagConstraints.gridwidth = 1;
        gridBagConstraints.gridy = ++gridy;

        gridx = 1;
        gridBagConstraints.gridx = gridx;
        operadoresPanel.add(joinTablesButton, gridBagConstraints);

        gridx = 2;
        gridBagConstraints.gridx = gridx;
        operadoresPanel.add(calcularTabla, gridBagConstraints);
        gridBagConstraints.gridx = ++gridx;
        operadoresPanel.add(resetButton, gridBagConstraints);

        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 4;
        add(jScrollPane1, gridBagConstraints);
        gridBagConstraints.gridy = 4;
        //todo
        gridBagConstraints.gridheight = 1;
        gridBagConstraints.gridy = 5;
        add(getScoringPanel(),gridBagConstraints);
        gridBagConstraints.gridheight = 4;
        //todo
        gridBagConstraints.gridy = 6;
        gridBagConstraints.gridheight = 2;
        add(operadoresPanel, gridBagConstraints);
    }

    /**
     * Establece la accion a ser realizada por el boton de negacion;
     */
    private void negacionButtonActionPerformed() {
        if (tableTitles.size() != 0) {
            char[] array = tableTitles.get(tableTitles.size() - 1).toCharArray();
            if (array[array.length - 1] == '(') {
                if (tableTitles.size() == 1) {
                    tableTitles.remove(0);
                    tableTitles.add(0, "(0");
                } else {
                    tableTitles.add("0");
                }
                addTableColumn(null);
            } else {
                if (checkIsNumber(tableTitles.get(tableTitles.size() - 1))) {
                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                            operandoOperando, "",
                            JOptionPane.WARNING_MESSAGE);
                } else {
                    tableTitles.add("0");
                    addTableColumn(null);
                }
            }
        } else {
            tableTitles.add("0");
            addTableColumn(null);
        }
        inputTextField.requestFocus();
    }

    /**
     * Establece la accion a ser realizada por el boton de conjuncion;
     */
    private void conjuncionButtonActionPerformed() {
        if (tableTitles.size() == 0) {
            JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                    listSize0, "",
                    JOptionPane.WARNING_MESSAGE);
        } else {
            char[] array = tableTitles.get(tableTitles.size() - 1).toCharArray();
            if (array[array.length - 1] == '(') {
                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                        parentesisOperando, "",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                if (checkIsNumber(tableTitles.get(tableTitles.size() - 1))) {
                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                            operandoOperando, "",
                            JOptionPane.WARNING_MESSAGE);
                } else {
                    tableTitles.add("7");
                    addTableColumn(null);
                }
            }
        }
        inputTextField.requestFocus();
    }

    /**
     * Establece la accion a ser realizada por el boton de disyuncion inclusiva;
     */
    private void disyuncionInclusivaButtonActionPerformed() {
        if (tableTitles.size() == 0) {
            JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                    listSize0, "",
                    JOptionPane.WARNING_MESSAGE);
        } else {
            char[] array = tableTitles.get(tableTitles.size() - 1).toCharArray();
            if (array[array.length - 1] == '(') {
                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), parentesisOperando, "",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                if (checkIsNumber(tableTitles.get(tableTitles.size() - 1))) {
                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                            operandoOperando, "",
                            JOptionPane.WARNING_MESSAGE);
                } else {
                    tableTitles.add("5");
                    addTableColumn(null);
                }
            }
        }
        inputTextField.requestFocus();
    }

    /**
     * Establece la accion a ser realizada por el boton de disyuncion exclusiva;
     */
    private void disyuncionExclusivaButtonActionPerformed() {
        if (tableTitles.size() == 0) {
            JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                    listSize0, "",
                    JOptionPane.WARNING_MESSAGE);
        } else {
            char[] array = tableTitles.get(tableTitles.size() - 1).toCharArray();
            if (array[array.length - 1] == '(') {
                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                        parentesisOperando, "",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                if (checkIsNumber(tableTitles.get(tableTitles.size() - 1))) {
                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                            operandoOperando, "",
                            JOptionPane.WARNING_MESSAGE);
                } else {
                    tableTitles.add("3");
                    addTableColumn(null);
                }
            }
        }
        inputTextField.requestFocus();
    }

    /**
     * Establece la accion a ser realizada por el boton de condicional;
     */
    private void condicionalButtonActionPerformed() {
        if (tableTitles.size() == 0) {
            JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                    listSize0, "",
                    JOptionPane.WARNING_MESSAGE);
        } else {
            char[] array = tableTitles.get(tableTitles.size() - 1).toCharArray();
            if (array[array.length - 1] == '(') {
                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                        parentesisOperando, "",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                if (checkIsNumber(tableTitles.get(tableTitles.size() - 1))) {
                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                            operandoOperando, "",
                            JOptionPane.WARNING_MESSAGE);
                } else {
                    tableTitles.add("1");
                    addTableColumn(null);
                }
            }
        }
        inputTextField.requestFocus();
    }

    /**
     * Establece la accion a ser realizada por el boton de bicondicional;
     */
    private void bicondicionalButtonActionPerformed() {
        if (tableTitles.size() == 0) {
            JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                    listSize0, "",
                    JOptionPane.WARNING_MESSAGE);
        } else {
            char[] array = tableTitles.get(tableTitles.size() - 1).toCharArray();
            if (array[array.length - 1] == '(') {
                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                        parentesisOperando, "",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                if (checkIsNumber(tableTitles.get(tableTitles.size() - 1))) {
                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                            operandoOperando, "",
                            JOptionPane.WARNING_MESSAGE);
                } else {
                    tableTitles.add("2");
                    addTableColumn(null);
                }
            }
        }
        inputTextField.requestFocus();
    }

    /**
     * Establece la accion a ser realizada por el boton de negacion conjunta;
     */
    private void negacionConjuntaButtonActionPerformed() {
        if (tableTitles.size() == 0) {
            JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                    listSize0, "",
                    JOptionPane.WARNING_MESSAGE);
        } else {
            char[] array = tableTitles.get(tableTitles.size() - 1).toCharArray();
            if (array[array.length - 1] == '(') {
                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), parentesisOperando, "",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                if (checkIsNumber(tableTitles.get(tableTitles.size() - 1))) {
                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                            operandoOperando, "",
                            JOptionPane.WARNING_MESSAGE);
                } else {
                    tableTitles.add("4");
                    addTableColumn(null);
                }
            }
        }
        inputTextField.requestFocus();
    }

    /**
     * Establece la accion a ser realizada por el boton de incompatibilidad;
     */
    private void incompatibilidadButtonActionPerformed() {
        if (tableTitles.size() == 0) {
            JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                    listSize0, "",
                    JOptionPane.WARNING_MESSAGE);
        } else {
            char[] array = tableTitles.get(tableTitles.size() - 1).toCharArray();
            if (array[array.length - 1] == '(') {
                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                        parentesisOperando, "",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                if (checkIsNumber(tableTitles.get(tableTitles.size() - 1))) {
                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                            operandoOperando, "",
                            JOptionPane.WARNING_MESSAGE);
                } else {
                    tableTitles.add("6");
                    addTableColumn(null);
                }
            }
        }
        inputTextField.requestFocus();
    }

    /**
     * Establece la accion a ser realizada por el boton de aceptar;
     */
    private void acceptButtonActionPerformed() {
        String input = inputTextField.getText();
        if (input.equals("")) {
            JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                    textBundle.getString(TextBundleEnum.WARNING_VALORES_NULOS.toString()) + "!", "",
                    JOptionPane.WARNING_MESSAGE);
        } else {
            int first = (input.replace("(", "")).length();
            int second = (input.replace(")", "")).length();
            if (!(first == 1 || second == 1 || first == 0 || second == 0)) {
                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                        textBundle.getString(TextBundleEnum.WARNING_UNICO_CARACTER_ATOMICAS.toString()) + "!", "",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                if (checkIsNumber(input)) {
                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                            textBundle.getString(TextBundleEnum.WARNING_NO_NUMEROS_ATOMICAS.toString()) + "!", "",
                            JOptionPane.WARNING_MESSAGE);
                } else {
                    if (tableTitles.size() != 0) {
                        char[] array = tableTitles.get(tableTitles.size() - 1).toCharArray();
                        if (input.charAt(0) == ')') {
                            if (array[array.length - 1] == '(') {
                                JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                                        textBundle.getString(TextBundleEnum.WARNING_EXPRESION_NULA.toString()) + "!",
                                        "", JOptionPane.WARNING_MESSAGE);
                            } else {
                                if (checkIsNumber("" + array[array.length - 1])) {
                                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                                            textBundle.getString(
                                                    TextBundleEnum.WARNING_OPERANDO_PARENTESIS.toString()) + "!", "",
                                            JOptionPane.WARNING_MESSAGE);
                                } else {
                                    input = tableTitles.get(tableTitles.size() - 1).concat(input);
                                    tableTitles.set(tableTitles.size() - 1, input);
                                }
                            }
                        } else {
                            if (array[array.length - 1] == '(') {//
                                input = tableTitles.get(tableTitles.size() - 1).concat(input);
                                tableTitles.set(tableTitles.size() - 1, input);
                            } else {
                                if (!checkIsNumber("" + input) && !checkIsNumber("" + array[array.length - 1])) {
                                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                                            textBundle.getString(
                                                    TextBundleEnum.WARNING_PROPOSICIONES_SEGUIDAS.toString()) + "!", "",
                                            JOptionPane.WARNING_MESSAGE);
                                } else {
                                    if (input.contains("(")) {
                                        tableTitles.set(tableTitles.size() - 1, tableTitles.get(tableTitles.size() - 1).concat(getParenthesis(input)));
                                    }
                                    input = input.replace("(", "");
                                    if (!input.equals("")) {
                                        tableTitles.add(input);
                                    }
                                }
                            }
                        }
                    } else {
                        tableTitles.add(input);
                    }
                }
                addTableColumn(null);
            }
        }
        inputTextField.setText("");
        inputTextField.requestFocus();
    }

    /**
     * Establece la accion a ser realizada por el boton de reset;
     */
    private void resetearButtonActionPerformed() {
        tableTitles = new ArrayList<String>();
        addTableColumn(null);
        inputTextField.requestFocus();
    }

    /**
     * Metoo auxiliar para agregar una columna;
     *
     * @param content
     */
    private void addTableColumn(Object[][] content) {
        if (content == null) {
            content = new Object[][]{};
        }
        table.setModel(new javax.swing.table.DefaultTableModel(
                content, tableTitles.toArray()
        ) {//this prevents the table being editable!

            public boolean isCellEditable(int row, int column) {
                return false;
            }
        }
        );

        JLabel label;
        String current;
        String parenthesis;
        for (int j = 0; j < tableTitles.size(); j++) {
            label = new JLabel();
            label.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            current = tableTitles.get(j).replace("(", "");
            current = current.replace(")", "");
            parenthesis = getParenthesis(tableTitles.get(j));
            table.getColumnModel().getColumn(j).setHeaderRenderer(new JComponentCellRenderer());
            label.setFont(new Font("Tahoma", 1, 16));
            if (current.equalsIgnoreCase("0")) {
                label.setText(parenthesis);
                if (isOpenParenthesisBeforeNegation(tableTitles.get(j))) {
                    label.setHorizontalTextPosition(SwingConstants.LEFT);
                }
                label.setIcon(Utiles.createImageIcon(URLEnum.getReference(URLEnum.NEGACION)));
                table.getColumnModel().getColumn(j).setHeaderValue(label);
            } else {
                if (current.equalsIgnoreCase("1")) {
                    label.setText(parenthesis);
                    label.setIcon(Utiles.createImageIcon(URLEnum.getReference(URLEnum.CONDICIONAL)));
                    table.getColumnModel().getColumn(j).setHeaderValue(label);
                } else {
                    if (current.equalsIgnoreCase("2")) {
                        label.setText(parenthesis);
                        label.setIcon(Utiles.createImageIcon(URLEnum.getReference(URLEnum.BICONDICIONAL)));
                        table.getColumnModel().getColumn(j).setHeaderValue(label);
                    } else {
                        if (current.equalsIgnoreCase("3")) {
                            label.setText(parenthesis);
                            label.setIcon(Utiles.createImageIcon(URLEnum.getReference(URLEnum.DISYUNCION_EXCLUSIVA)));
                            table.getColumnModel().getColumn(j).setHeaderValue(label);
                        } else {
                            if (current.equalsIgnoreCase("4")) {
                                label.setText(parenthesis);
                                label.setIcon(Utiles.createImageIcon(URLEnum.getReference(URLEnum.NEGACION_CONJUNTA)));
                                table.getColumnModel().getColumn(j).setHeaderValue(label);
                            } else {
                                if (current.equalsIgnoreCase("5")) {
                                    label.setText(parenthesis);
                                    label.setIcon(Utiles.createImageIcon(URLEnum.getReference(URLEnum.DISYUNCION_INCLUSIVA)));
                                    table.getColumnModel().getColumn(j).setHeaderValue(label);
                                } else {
                                    if (current.equalsIgnoreCase("6")) {
                                        label.setText(parenthesis);
                                        label.setIcon(Utiles.createImageIcon(URLEnum.getReference(URLEnum.INCOMPATIBILIDAD)));
                                        table.getColumnModel().getColumn(j).setHeaderValue(label);
                                    } else {
                                        if (current.equalsIgnoreCase("7")) {
                                            label.setText(parenthesis);
                                            label.setIcon(Utiles.createImageIcon(URLEnum.getReference(URLEnum.CONJUNCION)));
                                            table.getColumnModel().getColumn(j).setHeaderValue(label);
                                        } else {
                                            label.setText(" " + tableTitles.get(j));
                                            table.getColumnModel().getColumn(j).setHeaderValue(label);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            table.getTableHeader().revalidate();
        }
    }

    /**
     * Metodo que analiza si hay un parentesis abierto;
     *
     * @param parenthesis;
     * @return boolean - true si hay un parentesis abierto;
     */
    private boolean isOpenParenthesis(String parenthesis) {
        if (parenthesis.length() > 0) {
            return parenthesis.charAt(0) == '(';
        }
        return false;
    }

    /**
     * Analiza si hay un parentesis abierto antes de la negacion;
     *
     * @param expression - String expresion;
     * @return boolean;
     */
    private boolean isOpenParenthesisBeforeNegation(String expression) {
        return expression.indexOf("(") != -1 && expression.indexOf("(") < expression.indexOf("0");
    }

    /**
     * Verifica si el elemento analizado es un numero;
     *
     * @param input - String expresion;
     * @return boolean;
     */
    private boolean checkIsNumber(String input) {
        char[] array = input.toCharArray();
        char character;
        for (int j = 0; j < array.length; j++) {
            character = array[j];
            if (character == '0' || character == '1' || character == '2' || character == '3' || character == '4'
                    || character == '5' || character == '6' || character == '7' || character == '8' ||
                    character == '9') {
                return true;
            }
        }
        return false;
    }

    /**
     * Chequea si el elemento analizado es un operando;
     *
     * @param input - String expresion;
     * @return boolean - true si es un operando distinto de la negacion;
     */
    private boolean checkIsOperand(String input) {
        char[] array = input.toCharArray();
        char character;
        for (int j = 0; j < array.length; j++) {
            character = array[j];
            if (character == '1' || character == '2' || character == '3' || character == '4' || character == '5' ||
                    character == '6' || character == '7') {
                return true;
            }
        }
        return false;
    }

    /**
     * Crea una representacion String de la expresion formada por el usuario;
     *
     * @return
     */
    private String buildExpression() {
        int size = tableTitles.size();
        StringBuffer stringBuffer = new StringBuffer();
        for (int j = 0; j < size; j++) {
            stringBuffer.append(tableTitles.get(j));
        }
        return stringBuffer.toString();
    }

    /**
     * Crea una expresion que contiene todos los parentesis de la expresion pasada;
     *
     * @param current;
     * @return String;
     */
    private String getParenthesis(String current) {
        char parenthesisOpen = '(';
        char parenthesisClose = ')';
        char[] array = current.toCharArray();
        StringBuffer stringBuffer = new StringBuffer();
        for (int j = 0; j < array.length; j++) {
            if (array[j] == parenthesisOpen || array[j] == parenthesisClose) {
                stringBuffer.append("" + array[j]);
            }
        }
        return stringBuffer.toString();
    }

    /**
     * Metodo que muestra la tabla de verdad;
     */
    private void displayTruthTable() {
        addTableColumn(truthTable.getResult());
//        table.getColumnModel().getColumn(truthTable.getResultColumn()).setCellRenderer(new JComponentCellRendererExtended(Color.GREEN));

        inputTextField.requestFocus();
    }

    protected void setSaveActionListener() {
        class SaveTruthtableAction extends AbstractAction {
            public SaveTruthtableAction() {
                super("", Utiles.createImageIcon(URLEnum.getReference(URLEnum.SAVE_AS)));
            }

            public void actionPerformed(ActionEvent e) {
                if (truthTable == null) {
                    JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                            textBundle.getString(TextBundleEnum.WARNING_NO_GUARDO_TABLA_INVALIDA.toString()) + "!",
                            "", JOptionPane.WARNING_MESSAGE);
                } else {
                    String path = "";
                    int state = fileChooser.showSaveDialog(JOptionPane.getRootFrame());
                    if (state == JFileChooser.APPROVE_OPTION) {
                        path = fileChooser.getSelectedFile().getPath();
                        Utiles.saveTextFileAlertingOverwrite(path, ".xml", truthTable.toXML());
                    }
                }
            }
        }
        saveButton.setAction(new SaveTruthtableAction());
    }

    protected void setSaveButtonEnabled() {
        saveButton.setEnabled(true);
    }

    protected void setOpenActionListener() {
        class OpenTruthtableAction extends AbstractAction {
            public OpenTruthtableAction() {
                super("", Utiles.createImageIcon(URLEnum.getReference(URLEnum.OPEN)));
            }

            public void actionPerformed(ActionEvent e) {
                String path = "";
                int state = fileChooser.showOpenDialog(JOptionPane.getRootFrame());
                if (state == JFileChooser.APPROVE_OPTION) {
                    path = fileChooser.getSelectedFile().getPath();
                    try {
                        RandomAccessFile randomAccessFile = new RandomAccessFile(path, "r");
                        String xml = randomAccessFile.readUTF();
                        if (xml.startsWith(TruthTable.openTag())) {
                            resetearButtonActionPerformed();
                            truthTable = TruthTable.fromXML(xml);
                            getTableHeader(truthTable);
                            displayTruthTable();
                        } else {
                            JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                                    textBundle.getString(TextBundleEnum.WARNING_ARCHIVO_INCORRECTO_TABLA.toString()));
                        }
                    } catch (FileNotFoundException e1) {
                        e1.printStackTrace();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
            }
        }
        openButton.setAction(new OpenTruthtableAction());
    }

    protected void setOpenButtonEnabled() {
        openButton.setEnabled(true);
    }

    protected void setFocusOnComponent() {
        inputTextField.requestFocus();
    }

    /**
     * Forma el table header a partir de un TruthTable que se le pase;
     *
     * @param truthTable;
     */
    private void getTableHeader(TruthTable truthTable) {
        String expression = truthTable.getExpression();
        StringBuffer buffer = new StringBuffer();
        char[] expressionArray = expression.toCharArray();
        for (int j = 0; j < expressionArray.length; j++) {
            if (checkIsNumber("" + expressionArray[j])) {
                if (!buffer.toString().equals("")) {
                    inputTextField.setText(buffer.toString());
                    acceptButtonActionPerformed();
                    buffer = new StringBuffer();
                    performOperandAction("" + expressionArray[j]);
                }
            } else {
                buffer.append(expressionArray[j]);
            }
        }
        if (!buffer.toString().equals("")) {
            inputTextField.setText(buffer.toString());
            acceptButtonActionPerformed();
        }
    }

    /**
     * Coordina las acciones a ser realizadas por cada operando;
     *
     * @param operandString
     */
    private void performOperandAction(String operandString) {
        int operand = Integer.parseInt(operandString);
        switch (operand) {
            case 0:
                negacionButtonActionPerformed();
                break;
            case 1:
                condicionalButtonActionPerformed();
                break;
            case 2:
                bicondicionalButtonActionPerformed();
                break;
            case 3:
                disyuncionExclusivaButtonActionPerformed();
                break;
            case 4:
                negacionConjuntaButtonActionPerformed();
                break;
            case 5:
                disyuncionInclusivaButtonActionPerformed();
                break;
            case 6:
                incompatibilidadButtonActionPerformed();
                break;
            case 7:
                conjuncionButtonActionPerformed();
                break;
        }
    }

    private JPanel getScoringPanel(){
        JPanel panel = new JPanel();
        panel.add(addsPoints);
        panel.add(addsPointsField);
        panel.add(substractPoints);
        panel.add(substractPointsField);
        panel.setBackground(Color.WHITE);
        return panel;
    }

    private JSeparator getOperatorsPanelSeparator(){
        Dimension separatorDimension = new Dimension(600,10);
        JSeparator separator = new JSeparator(JSeparator.HORIZONTAL);
        separator.setForeground(Color.LIGHT_GRAY);
        separator.setPreferredSize(separatorDimension);
        return separator;
    }

    public TestExcercise getExercise() throws ExerciseNotBuiltException, PunctuationZeroException {
        if (addsPointsField.getText().equals("") ||substractPointsField.getText().equals("")) {
            throw new ExerciseNotBuiltException();
        }
        if (Integer.parseInt(addsPointsField.getText()) == 0) {
            throw new PunctuationZeroException();
        }
        TestExcercise testExcercise = new TestTruthTable();
        truthTable = new TruthTable(buildExpression());
        testExcercise.setExerciseData(truthTable);
        testExcercise.setIncorrectScore(Integer.parseInt(substractPointsField.getText()));
        testExcercise.setCorrectScore(Integer.parseInt(addsPointsField.getText()));
        testExcercise.setStudentsSolution(truthTable.getArrayToComplete());
        return testExcercise;
    }

    public void setExercise(TestExcercise testExerciseData) {
        truthTable = (TruthTable) testExerciseData.getExcerciseData();
        getTableHeader(truthTable);
        displayTruthTable();
    }

    public void reset() {
        resetearButtonActionPerformed();
        addsPointsField.setText("10");
        addsPointsField.setEditable(true);
        substractPointsField.setText("5");
        substractPointsField.setEditable(true);
    }
}
